Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.

...powered by www.netzwerkartist.de...

 << zurück
Visual C# 2005 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2005

Visual C# 2005
1.320 S., mit 2 CDs, 59,90 Euro
Galileo Computing
ISBN 3-89842-586-X
gp Kapitel 6 Vererbung, Polymorphie und Schnittstellen
  gp 6.1 Basisklassen und abgeleitete Klassen
    gp 6.1.1 Ableiten einer Klasse
    gp 6.1.2 Klassen, die nicht vererben können
    gp 6.1.3 Zusammenfassung
  gp 6.2 Konstruktoren in abgeleiteten Klassen
    gp 6.2.1 Die Konstruktoren der Klasse »GraphicCircle«
    gp 6.2.2 Der Zugriffsmodifizierer »protected«
    gp 6.2.3 Konstruktorverkettung
    gp 6.2.4 Destruktor-Verkettung
    gp 6.2.5 Der Stand des Projekts »CircleApplication«
    gp 6.2.6 Zusammenfassung
  gp 6.3 Die Methoden in einer abgeleiteten Klasse
    gp 6.3.1 Geerbte Methoden mit »new« verdecken
    gp 6.3.2 Überladen einer Basisklassenmethode
  gp 6.4 Ereignisse in der Vererbung
  gp 6.5 »Hat-eine«-Beziehungen (Aggregation)
    gp 6.5.1 Weiterleitung einer internen Objektreferenz
    gp 6.5.2 Verbergen des internen Objekts
    gp 6.5.3 Innere Klassen
  gp 6.6 Typumwandlung von Objektvariablen
    gp 6.6.1 Die implizite Typumwandlung von Objektreferenzen
    gp 6.6.2 Die explizite Typumwandlung von Objektreferenzen
    gp 6.6.3 Zusammenfassung
  gp 6.7 Abstrakte Klassen und Methoden
    gp 6.7.1 Abstrakte Definitionen
  gp 6.8 Polymorphie
    gp 6.8.1 Virtuelle Methoden
    gp 6.8.2 Inhomogene Mengen
    gp 6.8.3 Verdecken und Überschreiben geerbter Methoden
    gp 6.8.4 Überschreiben der Methode »ToString()« der Klasse »Object«
    gp 6.8.5 Versiegelte Methoden
    gp 6.8.6 Zusammenfassung
  gp 6.9 Erweiterung der Klassenhierarchie »CircleApplication«
    gp 6.9.1 Die Klasse »GeometricObject«
  gp 6.10 Schnittstellen
    gp 6.10.1 Einführung in die Schnittstellen
    gp 6.10.2 Schnittstellendefinition
    gp 6.10.3 Schnittstellenimplementierung
    gp 6.10.4 Typumwandlung mit dem »as«-Operator
    gp 6.10.5 Abstrakte Klassen vs. Schnittstellen
    gp 6.10.6 Zusammenfassung


Galileo Computing

6.4 Ereignisse in der Vererbuntoptop

In der Vererbungskette nehmen Ereignisse eine besondere Stellung ein. Um dies zu verdeutlichen, ist im folgenden Codefragment die Klasse ClassA definiert, die das Ereignis Hallo veröffentlicht.


class ClassA {
  public delegate void MyHandler();
  public event MyHandler Hallo;
  public void DoSomething() {
    if(Hallo != null)
      Hallo();
  }
}

Wie üblich wird ein Delegat definiert und anschließend das Ereignis vom Typ des Delegaten deklariert. Ausgelöst wird das Ereignis beim Aufruf von DoSomething. In der Methode Main der Klasse Program wird jetzt zu Testzwecken ein Objekt vom Typ der ClassA erzeugt und das Ereignis Hallo an den Ereignisempfänger MyTestMethod gebunden:


class Program {
  static void Main(string[] args) {
    ClassA obj = new ClassA();
    obj.Hallo += new ClassA.MyHandler(MyTestMethod);
    obj.DoSomething();
    Console.ReadLine();
  }
  public static void MyTestMethod() {
    Console.WriteLine("Ereignis ist ausgelöst.");
  }
}

Der Aufruf von DoSomething auf das ClassA-Objekt bewirkt, dass die vom Delegaten beschriebene Methode MyTestMethod ausgeführt und im Konsolenfenster


Ereignis ist ausgelöst

angezeigt wird.

Nun soll ClassB die Klasse ClassA ableiten. ClassB wird um die objektspezifische Methode RaiseEvent ergänzt, deren Aufruf ebenfalls die Auslösung des Ereignisses Hallo bewirkt. Unter der Annahme, dass sich ein Ereignis an die ableitende Klasse vererbt, kann die Auslösung des Ereignisses Hallo folgendermaßen implementiert werden:


class ClassB : ClassA {
  public void RaiseEvent() {
    if(Hallo != null)
      Hallo();
  }
}

Der Versuch der Kompilierung wird allerdings scheitern, weil die beiden Anweisungen in RaiseEvent einen Fehler verursachen. Der Fehlerbeschreibung des Compilers können wir entnehmen, dass der Bezeichner Hallo nicht erkannt wird. Selbst das Schlüsselwort base in der Anweisung


base.Hallo();

kann das nicht vermeiden. Der Grund dafür ist, dass Ereignisse immer an die Klasse gebunden sind, in der sie definiert sind.


Ein Ereignis kann nur in der ereignisdefinierenden Klasse ausgelöst werden und nicht in einer abgeleiteten Klasse.

Damit stellt sich die Frage, wie wir das Ereignis einer Basisklasse einer abgeleiteten Klasse zur Verfügung stellen können.

Die Lösung ist sehr einfach: Wir implementieren eine zusätzliche Methode in der Klasse, in der das Ereignis definiert ist. In dieser Methode lösen wir das Ereignis aus. In unserem Beispiel müssten wir demnach die Klasse ClassA wie folgt ergänzen bzw. ändern:


class ClassA {
  public delegate void MyHandler();
  public event MyHandler Hallo;
  public void DoSomething() {
    // -------- Änderung --------
    OnHallo();
  }
  // -------- Neu --------
  public void OnHallo() {
    if(Hallo != null)
      Hallo();
  }
}

Die Methode OnHallo berücksichtigt jetzt die Bedürfnisse einer ableitenden Klasse. In OnHallo wird das Ereignis Hallo ausgelöst, was keine Komplikationen mehr verursacht, da das Ereignis in derselben Klasse definiert ist. Außerdem wird die Methode OnHallo nun auch aus der Methode DoSomething heraus aufgerufen, was allerdings nicht zwingend notwendig ist.

Kommen wir zurück zur abgeleiteten Klasse ClassB. In Kenntnis der Methode OnHallo sollte die Anweisung in der Methode RaiseEvent wie folgt aussehen:


class ClassB : ClassA {
  public void RaiseEvent() {
    this.OnHallo();
  }
}

Das Ereignis wird nicht mehr direkt aufgerufen, sondern die geerbte Methode OnHallo, die ihrerseits die Ereignisauslösung richtig delegiert.

Sehen wir uns zum Abschluss den zusammengefassten Code an.


// --------------------------------------------------------------
// Beispiel: ...\Kapitel 6\Ereignisse 
// -------------------------------------------------------------- 
class Program {
  static void Main(string[] args) {
    ClassB obj = new ClassB();
    obj.Hallo += new ClassB.MyHandler(MyTest);
    obj.RaiseEvent();
    Console.ReadLine();
  }
  public static void MyTest() {
    Console.WriteLine("Ereignis ist ausgelöst.");
  }
}
// ----- Basisklasse -----
class ClassA {
  public delegate void MyHandler();
  public event MyHandler Hallo;
  public void DoSomething() {
    OnHallo();
  }
  public void OnHallo() {
    if(Hallo != null)
      Hallo();
  }
}
// ----- abgeleitete Klasse -----
class ClassB : ClassA {
   public void RaiseEvent() {
     this.OnHallo();
  }
}

 << zurück
  
  Zum Katalog
Zum Katalog: Visual C# 2005
Visual C# 2005
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Fortgeschrittene Programmierung mit Visual C# 2005






 Fortgeschrittene
 Programmierung
 mit Visual C# 2005


Zum Katalog: Einstieg in Visual C# 2005






 Einstieg in
 Visual C# 2005


Zum Katalog: Einstieg in Visual Basic 2005






 Einstieg in
 Visual Basic 2005


Zum Katalog: Visual Basic 2005






 Visual Basic 2005


Zum Katalog: Java ist auch eine Insel






 Java ist auch eine
 Insel


Zum Katalog: Konzepte und Lösungen für Microsoft-Netzwerke






 Konzepte und
 Lösungen für
 Microsoft-Netzwerke


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo








Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de